package com.dwxt.mall.service;

import com.dwxt.common.base.*;
import com.dwxt.common.util.JsonUtils;
import com.dwxt.common.util.OkHttpUtils;
import com.dwxt.common.util.PartyUtil;
import com.dwxt.mall.constant.OrderStatus;
import com.dwxt.mall.constant.PayCategory;
import com.dwxt.mall.dao.PayOrderMapper;
import com.dwxt.mall.dao.ProductCategoryMapper;
import com.dwxt.mall.dao.ReceiptAddressMapper;
import com.dwxt.mall.entity.*;
import com.dwxt.mall.entity.vo.OrderVO;
import com.dwxt.mall.service.feign.UserService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class OrderService {
    @Autowired
    private PayOrderMapper orderMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private ProductService productService;

    @Value("${dongMei.url}")
    private String dongMeiUrl;

    @Autowired
    private ProductCategoryMapper productCategoryMapper;

    @Autowired
    private ReceiptAddressMapper receiptAddressMapper;

    @Autowired
    private AsyncService asyncService;

    public BaseResult validOrder(PayOrder order, Product product) {
        if (product.getIsShelf() == YesOrNo.NO) {
            log.error("商品已下架：0");
            return BaseResult.build(StatusCode.ORDER_PURCHASE_FAIL);
        }
        //获取用户信息
        JSONObject user = JSONObject.fromObject(userService.selectUserByKey(PartyUtil.getCurrentUserId()).getData());
        int integral = user.getInt("integral");
        //积分校验
        //定积分
        double totalPrice;
        if (product.getPayCategory() == PayCategory.definiteIntegral) {
            int needIntegral = product.getIntegral() * order.getNumber();
            if (integral < needIntegral || needIntegral != order.getIntegral()) {
                log.error("积分不足：1");
                return BaseResult.build(StatusCode.ORDER_PURCHASE_FAIL);
            }
            //totalPrice = order.getNumber() * product.getPrice();
            totalPrice = new BigDecimal(order.getNumber().toString()).multiply(new BigDecimal(product.getPrice().toString())).doubleValue();
        } else {
            //动积分
            if (integral < order.getIntegral()) {
                log.error("积分不足：2");
                return BaseResult.build(StatusCode.ORDER_PURCHASE_FAIL);
            }
            totalPrice = new BigDecimal(order.getNumber().toString()).multiply(new BigDecimal(product.getPrice().toString())).subtract(new BigDecimal(
                    String.valueOf(order.getIntegral() / 1000))).doubleValue();
            //totalPrice = order.getNumber() * product.getPrice() - order.getIntegral() / 1000;
        }
        //价格校验
        if (totalPrice != order.getRealPrice() || totalPrice < 0) {
            log.error("价格不对：3,totalPrice:{},realPrice:{}", totalPrice, order.getRealPrice());
            return BaseResult.build(StatusCode.ORDER_PURCHASE_FAIL);
        }


        //限购
        if (product.getIsLimit() == YesOrNo.YES) {
            int num = sumUserPurchaseProductNum(order.getProductId());
            if (num + order.getNumber() > product.getLimitNumber()) {
                log.error("超出限购：5");
                return BaseResult.build(StatusCode.PRODUCT_LIMIT);
            }
        }
        //库存校验
        int stock = product.getStock() - order.getNumber();
        if (stock < 0) {
            log.error("库存不足：3");
            return BaseResult.build(StatusCode.PRODUCT_STOCK_NOT_ENOUGH);
        }
        product.setStock(stock);
        int i = productService.updateProductStock(product);
        if (i < 1) {
            log.error("库存不足：4");
            return BaseResult.build(StatusCode.PRODUCT_STOCK_NOT_ENOUGH);
        }
        return null;
    }

    private int sumUserPurchaseProductNum(Integer productId) {
        List<String> statusList = new ArrayList<>();
        statusList.add(OrderStatus.PAY);
        statusList.add(OrderStatus.SHIP);
        statusList.add(OrderStatus.RECEIPT);
        statusList.add(OrderStatus.REQUEST_REFUND);
        statusList.add(OrderStatus.REFUND);
        statusList.add(OrderStatus.REFUND_FAIL);
        PayOrderExample example = new PayOrderExample();
        example.createCriteria().andUserIdEqualTo(PartyUtil.getCurrentUserId()).andProductIdEqualTo(productId).andStatusIn(statusList);
        List<PayOrder> orders = orderMapper.selectByExample(example);
        int sum = orders.stream().mapToInt(order -> order.getNumber()).sum();
        return sum;
    }

    @Async("myExecutor")
    public void changUserInfoWithWxAndZFBPay(PayOrder order) {
        if (OrderStatus.PLACE.equals(order.getStatus())) {
            //更改用户积分，生成积分记录
            if (order.getIntegral() > 0) {
                //消耗积分
                userService.updateIntegral(-order.getIntegral(), order.getId(), order.getName(), order.getUserId());
            }
            BaseResult baseResult = userService.selectRuleByCategory(IntegralCategory.SHOP_REWARD);
            int integral = JSONObject.fromObject(baseResult.getData()).getInt("integral");
            integral = (int) Math.floor(order.getRealPrice()) * integral;
            if (integral > 0) {
                //奖励积分
                userService.updateIntegral(integral, order.getId(), IntegralCategory.SHOP_REWARD, order.getUserId());
            }
            //更改订单状态
            order.setStatus(OrderStatus.PAY);
            order.setPayTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }

        //消息通知
        asyncService.reply(order);
    }

    /**
     * 更改订单状态，恢复库存
     **/
    @Transactional
    public void cancelOrfailOrder(PayOrder order, String status) {
        if (OrderStatus.PLACE.equals(order.getStatus())) {
            Product product = productService.selectProductByPrimaryKey(order.getProductId());
            product.setStock(product.getStock() + order.getNumber());
            productService.updateProductStock(product);
            order.setStatus(status);
            orderMapper.updateByPrimaryKeySelective(order);
        }
    }

    public List<OrderVO> selectMallOrderList(Integer type, String status) {
        return orderMapper.selectMallOrderList(PartyUtil.getCurrentUserId(), status, type);
    }

    public void insertSelective(PayOrder order) {
        orderMapper.insertSelective(order);
    }

    public PayOrder selectByPrimaryKey(String id) {
        return orderMapper.selectByPrimaryKey(id);
    }

    public void cancelOrder(String id) {
        PayOrder payOrder = orderMapper.selectByPrimaryKey(id);
        if (payOrder != null && payOrder.getStatus().equalsIgnoreCase(OrderStatus.PLACE)) {
            //订单取消，加库存
            cancelOrfailOrder(payOrder, OrderStatus.CANCEL);
        }
    }

    public void updateByPrimaryKeySelective(PayOrder order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    public List<PayOrder> selectOrderByCategoryAndStatus(String category, String status) {
        PayOrderExample example = new PayOrderExample();
        example.createCriteria().andCategoryEqualTo(category).andStatusEqualTo(status);
        return orderMapper.selectByExample(example);
    }

    public BaseResult reqRefund(String orderId, String reason) {
        List<String> list = new ArrayList<>();
        list.add(OrderStatus.PAY);
        list.add(OrderStatus.SHIP);
        list.add(OrderStatus.RECEIPT);
        list.add(OrderStatus.REFUND_FAIL);

        PayOrder order = orderMapper.selectByPrimaryKey(orderId);
        if (!list.contains(order.getStatus())) {
            return BaseResult.build(StatusCode.REFUND_ERROR);
        } else if (order.getRealPrice() <= 0) {
            return BaseResult.build(StatusCode.REFUND_PRICE_ERROR);
        } else {
            order.setStatus(OrderStatus.REQUEST_REFUND);
            order.setUserRefundReason(reason);
            order.setReqRefundTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
            return BaseResult.ok();
        }
    }

    public BaseResult selectDetailByKey(String id, Integer type) {
        //自己的订单
        PayOrder order = orderMapper.selectByPrimaryKey(id);
        if (type == 1) {
            //PayOrder order = orderMapper.selectByPrimaryKey(id);
            Product product = productService.selectProductByPrimaryKey(order.getProductId());
            OrderVO orderVO = JsonUtils.jsonToPojo(JsonUtils.objectToJson(order), OrderVO.class);
            orderVO.setProduct(product);
            return BaseResult.ok(orderVO);
        } else {
            //获取动美订单详情
            com.alibaba.fastjson.JSONObject result = selectDetailDongMei(id);
            int errorcode1 = result.getInteger("errorcode");
            if (errorcode1 != 0) {
                log.error("result========>" + result);
                return BaseResult.build(result.getInteger("errorcode"), result.getString("errormessage"), null);
            } else {
                return BaseResult.ok(result.getJSONObject("value"));
            }
        }
    }

    public com.alibaba.fastjson.JSONObject selectDetailDongMei(String id) {
        Map<String, String> headers = new HashMap<>();
        headers.put("username", "15123058497");
        headers.put("Signature", "2ddfeb530a2e81c9f45ed37398e6a20ec357d1c9");
        String url = dongMeiUrl + "order?OrderNumber=" + id;
        com.alibaba.fastjson.JSONObject result = com.alibaba.fastjson.JSONObject.parseObject(OkHttpUtils.synGet(url, headers));
        //JSONObject result = JSONObject.fromObject(OkHttpUtils.synGet(url, headers));
        return result;
    }

    public void createOrderLocal(PayOrder order, Product product, String orderId, Object params) {
        if (order.getRealPrice() == 0) {
            order.setStatus(OrderStatus.PAY);
        } else {
            order.setStatus(OrderStatus.PLACE);
        }
        if (params instanceof String) {
            order.setNonceStr(orderId);
            order.setPrepayId(params.toString());
            order.setPayMethod(PurchaseMethod.ZFB);
        } else {
            Map<String, String> resp = (Map<String, String>) params;
            order.setNonceStr(resp.get("noncestr"));
            order.setPrepayId(resp.get("prepayid"));
            order.setPayMethod(PurchaseMethod.WX);
        }
        //查找商品种类,生成本地订单属性
        ProductCategory productCategory = productCategoryMapper.selectByPrimaryKey(product.getCategoryId());
        order.setId(orderId);
        order.setSupplierId(product.getSupplierId());
        order.setCategory(productCategory.getName());
        order.setName(product.getName());
        if ("培训券".equals(productCategory.getName())) {
            order.setTicketCode((System.currentTimeMillis() + "").substring(1));
        }
        order.setUserId(PartyUtil.getCurrentUserId());
        order.setExpireTime(new Date(System.currentTimeMillis() + 15 * 60 * 1000));
        //查找地址信息，生成本地订单属性
        if (order.getAddressId() != null) {
            ReceiptAddress address = receiptAddressMapper.selectByPrimaryKey(order.getAddressId());
            order.setUsername(address.getUsername());
            order.setPhone(address.getPhone());
            order.setAddress(address.getAddress());
        }
        //生成本地订单
        insertSelective(order);
    }

    public BaseResult cancelRefund(String orderId) {
        PayOrder order = orderMapper.selectByPrimaryKey(orderId);
        if (order != null && order.getStatus().equalsIgnoreCase(OrderStatus.REQUEST_REFUND)) {
            order.setStatus(OrderStatus.PAY);
            orderMapper.updateByPrimaryKeySelective(order);
        }
        return BaseResult.ok();
    }
}
